
using System;
using System.Collections;
using System.Collections.Generic;
using cfg;
using MyFrame.Pool;
using MyFrame.Single;
using Platform.Skill;
using Platform.Skill.Deployer;
using Platform.Skill.Indicator;
using UnityEngine;
using static Entity;


namespace Platform.Skill.Core
{
    //参考：https://zhuanlan.zhihu.com/p/513705768
    /// <summary>
    /// skilldataSo 有着全局的属性，所以如果要给怪物，最好是重新创建新的SO，用表格是最方便的
    /// 全局变量的好处是多个预制体也可以共享同一份数据，也就无需再有一个管理释放器的层级了
    /// </summary>
    public class SkillMgr : MonoBehaviour
    {
        const string SKILL_PATH = "";
        // const string SKILL_PATH = "SkillPrefab/";
        public SkillDataSO skillDataList;
       
        public SkillData currentSkill;
        public Entity entity;

       

        // 避免填充技能重复执行冷却
        private bool isColldown;


        void Start()
        {
            skillDataList = GetComponent<Entity>().stats.skillDataList;
            if (skillDataList != null)
            {
                // skillData.ResetSkills();
                Init();
            }
            entity = GetComponent<Entity>();
        }

        void Init()
        {
            foreach (var skillData in skillDataList.skills)
            {
                if (!skillData.prefabName.IsNullOrEmpty())
                {
                    // PoolMgr.Instance.CreatePool(SKILL_PATH + skill.prefabName, 5);
                    // skill.skillPrefab = Resources.Load<GameObject>("/SkillPrefab" + skill.prefabName);
                    skillData.owner = gameObject;
                    skillData.attackTargets = new HashSet<Transform>();

                    // 提前填充  技能预制体
                    if (skillData.backfillCount > 0)
                    {
                        skillData.backfills = new List<GameObject>();
                        for (int i = 0; i < skillData.backfillCount; i++)
                        {
                            BackfillObj(skillData);
                        }
                    }
                }
            }
        }


        #region  使用技能
        /// <summary>
        /// 准备技能
        /// </summary>
        /// <param name="skillEnum"></param>
        /// <returns></returns>
        public SkillData PrepareSkill(SkillEnum skillEnum)
        {
            SkillData skillData = skillDataList.skills.Find(x => x.skillId == (int)skillEnum);
            if (skillData.backfillCount > 0)
            {
                return skillData;
            }
            if (skillData != null && skillData.cdRemain <= 0)//这里还有技能消耗值的判断
                return skillData;
            else
                return null;
        }

        /// <summary>
        /// 生成技能
        /// </summary>
        /// <param name="skillEnum"></param>
        /// <param name="targetPos">技能生成和目标位置</param>
        /// <returns></returns>
        public SkillData UseSkill(SkillEnum skillEnum, Vector3 targetPos = default)
        {
            var skillData = PrepareSkill(skillEnum);
            if (skillData == null) return null;
            currentSkill = skillData;

            if (!skillData.prefabName.IsNullOrEmpty())
            {
                GameObject skillPrefab = null;
                Vector3 generatePos = Tool.GetEntityCenterByCollider(transform);
                // 自指多段技能，不重复创建预制体
                // 传送的需求是自身被再次创建时触发下一段， 依赖于自身 无法使用事件
                if (skillEnum == skillData.nextSkill)
                {
                    if (skillData.skillPrefab != null)
                    {
                        skillPrefab = skillData.skillPrefab;
                    }
                    else
                    {
                        var prefab = Resources.Load<GameObject>(SKILL_PATH + skillData.prefabName);
                        skillPrefab = Instantiate(prefab, generatePos, transform.rotation);
                    }
                    skillPrefab.SetActive(true);
                }
                // 填充式技能
                else if (skillData.backfillCount > 0)
                {
                    if (skillData.backfills.Count > 0)
                    {
                        skillPrefab = skillData.backfills[0];
                        skillPrefab.SetActive(true);
                        skillData.backfills.RemoveAt(0);
                    }
                }
                else
                {
                    //创建技能预制体
                    skillPrefab = PoolMgr.Instance.GetObj(SKILL_PATH + skillData.prefabName,generatePos, transform.rotation);
                }
                skillData.skillPrefab = skillPrefab;

                if (targetPos != default)
                {
                    skillPrefab.transform.position = targetPos;
                    skillData.targetPos = targetPos;
                }

                //传递技能数据给技能释放器
                SkillDeployer deployer = skillPrefab != null ? skillPrefab.GetComponent<SkillDeployer>() : null;

                if (deployer != null)
                {
                    deployer.SkillData = skillData;
                    //释放器释放技能
                    deployer.DeploySkill();
                }
            }

            //防止装填的冷却重复触发
            if (!isColldown)
                StartCoroutine(CoolTimeDown(skillData));
            return skillData;
        }
        public SkillData UseSkill(int id)
        {
            if (Enum.TryParse(id.ToString(), out SkillEnum skillEnum))
            {
                return UseSkill(skillEnum);
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 装填技能预制体
        /// </summary>
        private void BackfillObj(SkillData skillData)
        {
            Debug.Log("装填技能预制体");
            var obj = PoolMgr.Instance.GetObj(SKILL_PATH + skillData.prefabName);
            obj.SetActive(false);
            skillData.backfills.Add(obj);
        }


        //协程实现技能冷却  
        private IEnumerator CoolTimeDown(SkillData skillData)
        {
            isColldown = true;
            skillData.cdRemain = skillData.cooldown;
            while (skillData.cdRemain > 0)
            {
                yield return new WaitForSeconds(0.1f);
                skillData.cdRemain -= 0.1f;
            }
            isColldown = false;

            //冷却完毕，如果是填充技能，递归
            if (skillData.backfillCount > 0)
            {
                if (skillData.backfills.Count < skillData.backfillCount)
                {
                    BackfillObj(skillData);
                    StartCoroutine(CoolTimeDown(skillData));
                }
            }
        }
        #endregion


       

    }
}